/**
 * Copyright © 2013 Creativor Studio.
 * About license information, please see LICENSE.txt.
 */
package org.creativor.rayson.share.transport.http;

import java.util.Arrays;

import org.creativor.rayson.share.annotation.NotNull;
import org.creativor.rayson.util.LangUtil;

/**
 * An abstract implementation of {@link HttpMessage}.
 * 
 * @author creativor
 */
public abstract class AbstractHttpMessage implements HttpMessage {

	private HttpStartLine startLine;
	private final HttpHeaders headers;
	private byte[] body;
	private int bodyLength;

	protected AbstractHttpMessage() {
		this.headers = new HttpHeaders();
		body = new byte[0];
		bodyLength = -1;
	}

	protected AbstractHttpMessage(@NotNull final HttpHeaders headers) {
		this.headers = headers;
		body = new byte[0];
	}

	protected AbstractHttpMessage(@NotNull final HttpStartLine startLine) {
		this();
		LangUtil.testNullArgument(startLine, "Start line");
		this.startLine = startLine;
	}

	@Override
	public final byte[] getBody() {
		return body;
	}

	/**
	 * Get {@link HttpConstants#CONTENT_LENGTH_HEADER_NAME} header value of this
	 * message.
	 * 
	 * @return Found header value. Or 0 if no such header found.
	 */
	public final int getBodyLength() {
		if (bodyLength >= 0)
			return bodyLength;
		final HttpHeader header = headers
				.get(HttpConstants.CONTENT_LENGTH_HEADER_NAME);
		if (header == null)
			return 0;
		else
			return Integer.valueOf(header.getValue());
	}

	@Override
	public final HttpHeaders getHeaders() {
		return headers;
	}

	@Override
	public HttpStartLine getStartLine() {
		return startLine;
	}

	/**
	 * @param body
	 *            the body to set
	 */
	protected void setBody(@NotNull final byte[] body) {
		LangUtil.testNullArgument(body, "Message body");
		this.body = body;
	}

	/**
	 * @param bodyLength
	 */
	void setBodyLength(final int bodyLength) {
		this.bodyLength = bodyLength;
	}

	/**
	 * @param startLine
	 *            the start line to set
	 */
	protected void setStartLine(@NotNull final HttpStartLine startLine) {
		this.startLine = startLine;
	}

	@Override
	public String toString() {
		final StringBuffer sb = new StringBuffer();
		sb.append("{");
		sb.append("startLine:" + this.startLine);
		sb.append(", headers:" + this.headers);
		sb.append(", body:" + Arrays.toString(this.body));
		sb.append("}");
		return sb.toString();
	}
}